package ac.github.os.internal.core.action.store

import ac.github.os.internal.core.action.Action
import ac.github.os.internal.core.config.StringConfig
import ac.github.os.internal.core.config.get
import ac.github.os.internal.core.store.Store
import ac.github.os.internal.session.Cache
import ac.github.os.internal.session.Session
import taboolib.common.platform.Awake
import taboolib.common5.Coerce

abstract class StoreAction : Action {

    override val type: Action.Type
        get() = Action.Type.AIR

    abstract val name: String

    override fun onExecute(session: Session, cache: Cache, config: StringConfig) {
        val key = config.get<String>("k") ?: return
        val value = config.get<String>("v") ?: return
        eval(key, value).eval()
    }

    abstract fun eval(key: String, value: Any): StoreOperation

    override val namespace: String
        get() = "store:$name"
}

@Awake
class StoreAddAction : StoreAction() {
    override val name: String
        get() = "add"

    override fun eval(key: String, value: Any) = StoreAdd(key, value)
}

@Awake
class StoreSubtractAction : StoreAction() {
    override val name: String
        get() = "sub"

    override fun eval(key: String, value: Any) = StoreSubtract(key, value)
}

@Awake
class StoreSetAction : StoreAction() {
    override val name: String
        get() = "set"

    override fun eval(key: String, value: Any) = StoreSet(key, value)
}

@Awake
class StoreMultiplyAction : StoreAction() {
    override val name: String
        get() = "mult"

    override fun eval(key: String, value: Any) = StoreMultiply(key, value)
}

@Awake
open class StoreDivisionAction : StoreAction() {
    override val name: String
        get() = "div"

    override fun eval(key: String, value: Any) = StoreDivision(key, value)
}

abstract class StoreOperation(val key: String) {

    abstract fun eval()

}

class StoreSubtract(key: String, val value: Any) : StoreOperation(key) {
    override fun eval() {
        Store.GLOBAL?.get(key)?.subtract(Coerce.toFloat(value))
    }
}

class StoreSet(key: String, val value: Any) : StoreOperation(key) {
    override fun eval() {
        Store.GLOBAL?.set(key,Store.Data(value))
    }
}

class StoreAdd(key: String, val value: Any) : StoreOperation(key) {
    override fun eval() {
        Store.GLOBAL?.get(key)?.add(Coerce.toFloat(value))
    }
}

class StoreMultiply(key: String, val value: Any) : StoreOperation(key) {
    override fun eval() {
        Store.GLOBAL?.get(key)?.multiply(Coerce.toFloat(value))
    }
}

class StoreDivision(key: String, val value: Any) : StoreOperation(key) {
    override fun eval() {
        Store.GLOBAL?.get(key)?.division(Coerce.toFloat(value))
    }
}